
package servidor.bbdd;

import beans.Estudiant;
import beans.ParticipacioEnquesta;
import beans.PreguntaEnquesta;
import beans.TotalsPregunta;
import common.EOlympicsException;
import common.EOlympicsHelper;
import common.TDSLanguageUtils;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Classe GestorParticipacionsEnquestes
 * @author Juan Luís Chávez Lobato i Jesús Hernàndez Garcia
 */

public class GestorParticipacionsEnquestes {
    
    private GestorDiscConnexio gestor;
    private Connection connexio;

    /**
     * Constructor de la classe GestorParticipacionsEnquestes
     * Crea un nou gestor de disc.
     */
    public GestorParticipacionsEnquestes() throws EOlympicsException {
        this.gestor = new GestorDiscConnexio();
        this.gestor.obreConnexioBD();
        this.connexio = gestor.getConnexio();
    }

    /**
     * Constructor de la classe GestorParticipacionsEnquestes
     * Utilitza el gestor de disc passat com a paràmetre
     * @param gdc connexió a la BD de tipus GestorDiscConnexio
     */
    public GestorParticipacionsEnquestes(GestorDiscConnexio gdc) {
        this.gestor   = gdc;
        this.connexio = gdc.getConnexio();
    }
    
    /**
     * Inserta a la BD una participació a una pregunta de l'enquesta
     * per part d'un estudiant
     * @param est Estudiant que respon
     * @param pre pregunta que ha valorat
     * @return true si la inserció s'ha fet
     * @exception EOlympicsException
     */
    public boolean inserirParticipacio(Estudiant est, PreguntaEnquesta pre, int valoracio) throws EOlympicsException {
        boolean ok = false;
        try {

            String insert = "INSERT INTO PARTICIPACION_ENCUESTA (login_estudiante,"+
                            "num_pregunta, valoracion, fecha_respuesta) VALUES (?, ?, ?, ?)";
            PreparedStatement pst = gestor.crearPreparedStatement(insert);
            pst.setString(1, est.getLogin());
            pst.setInt(2, pre.getNum());
            pst.setInt(3, valoracio);
            // Agafar data actual i transformar-la per a poder insertar-la a la BD
            Date avui = new Date(System.currentTimeMillis());
            pst.setDate(4, avui);
            pst.execute();
            ok = true;
            pst.close();
        } catch (SQLException sqle) {
            System.out.println(sqle.getMessage());
            throw new EOlympicsException(EOlympicsException.ERR_SQL);
        } catch (Exception e) {
            System.out.println(e.getMessage());
            throw new EOlympicsException(EOlympicsException.ERR_DESC_EXEC);
        }

        return ok;
    }
    
    /**
     * Mètode que obté la participació d'un estudiant pel seu Login
     * @param login Login de l'estudiant
     * @return Llista de la participació de l'estudiant amb Login igual al passat com a paràmete
     * @exception EOlympicsException
     */
    public List<ParticipacioEnquesta> obtenirParticipacioEstudiant(String login) throws EOlympicsException {
        List<ParticipacioEnquesta> LlistaPartEst = new ArrayList<ParticipacioEnquesta>();
        ParticipacioEnquesta partEst;

        try {
            Statement sentencia = gestor.creaSentencia();
            String select = "SELECT * FROM PARTICIPACION_ENCUESTA " + 
                            "WHERE login_estudiante = '" + login + "'";
            ResultSet rs = sentencia.executeQuery(select);
            while (rs.next()) {
                partEst = new ParticipacioEnquesta(rs.getString(1), rs.getInt(2), 
                                                   rs.getInt(3), rs.getDate(4));
                LlistaPartEst.add(partEst);
            }
            rs.close();
            sentencia.close();
        } catch (SQLException sqle) {
            System.out.println(sqle.getMessage());
            throw new EOlympicsException(EOlympicsException.ERR_SQL);
        } catch (Exception e) {
            System.out.println(e.getMessage());
            throw new EOlympicsException(EOlympicsException.ERR_DESC_EXEC);
        }
        return LlistaPartEst;


    }
    
    /**
     * Mètode que obté el quadre de resultats finals
     * @param login Login de l'estudiant per veure el seu vot
     * @param filterByUniversitat flag per filtrar per Universitat
     * @param idUni Universitat per filtrar
     * @return Llista dels totals de la enquesta
     * @exception EOlympicsException
     */    
    public List<TotalsPregunta> obtenirTotals(String login, 
            boolean filterByUniversitat, int idUni) throws EOlympicsException{
        
        Map<Integer,TotalsPregunta> valoracionsTotals = new HashMap<Integer,TotalsPregunta>();
        TotalsPregunta totals;
        try {
            Statement sentencia = gestor.creaSentencia();
            String select = "select p.num_pregunta, p.texto, pe.valoracion, e.login_estudiante " +
            "from estudiante as e, " + 
            "participacion_encuesta as pe, " +
            "pregunta_encuesta as p, " +
            "universidad as u " +
            "where p.num_pregunta = pe.num_pregunta " +
            "and e.login_estudiante = pe.login_estudiante " +
            "and u.id_universidad = e.id_universidad ";
            if (filterByUniversitat){
                select = select + "and u.id_universidad = " + idUni + " ";
            }
            select = select + "order by e.login_estudiante ";
            ResultSet rs = sentencia.executeQuery(select);
            while (rs.next()) {
                if(valoracionsTotals.containsKey(rs.getInt(1))){
                    totals = valoracionsTotals.get(rs.getInt(1));
                }else{
                    totals = new TotalsPregunta(rs.getString(2), 0, 0, 0, 0, 0, "");
                }
                valoracionsTotals.put(rs.getInt(1), 
                        actualitza(totals, rs.getInt(3),
                                    login.equalsIgnoreCase(rs.getString(4)))); 
            }
            rs.close();
            sentencia.close();
        } catch (SQLException sqle) {
            System.out.println(sqle.getMessage());
            throw new EOlympicsException(EOlympicsException.ERR_SQL);
        } catch (Exception e) {
            System.out.println(e.getMessage());
            throw new EOlympicsException(EOlympicsException.ERR_DESC_EXEC);
        }
        
        return new ArrayList<TotalsPregunta>(valoracionsTotals.values());
    }
    
    /**
     * Mètode auxiliar per actualitzar els comptadors dels totals
     * @param totals fila retornada per actualitzar
     * @param valoracion nova valoració per comptar
     * @param isEstudiant Flag per saber si la valoració és la del propi estudiant
     * @return Valoració actualitzada
     */    
    private TotalsPregunta actualitza(TotalsPregunta totals, int valoracion, boolean isEstudiant){
        int valor;
        switch (valoracion){
            case EOlympicsHelper.MOLT_DESACORD:
                valor = totals.getTotalsMoltDesacord();
                totals.setTotalsMoltDesacord(++valor);
                if (isEstudiant){
                    totals.setVotEstudiant(TDSLanguageUtils.getMessage("resposta0"));
                }
                break;
            case EOlympicsHelper.MICA_DESACORD:
                valor = totals.getTotalsMicaDesacord();
                totals.setTotalsMicaDesacord(++valor);
                if (isEstudiant){                
                    totals.setVotEstudiant(TDSLanguageUtils.getMessage("resposta1"));
                }
                break;
            case EOlympicsHelper.INDIFERENT:
                valor = totals.getTotalsIndiferent();
                totals.setTotalsIndiferent(++valor);
                if (isEstudiant){
                    totals.setVotEstudiant(TDSLanguageUtils.getMessage("resposta2"));
                }
                break;
            case EOlympicsHelper.MICA_ACORD:
                valor = totals.getTotalsMicaAcord();
                totals.setTotalsMicaAcord(++valor);
                if (isEstudiant){
                    totals.setVotEstudiant(TDSLanguageUtils.getMessage("resposta3"));
                }
                break;
            case EOlympicsHelper.MOLT_ACORD:
                valor = totals.getTotalsMoltAcord();
                totals.setTotalsMoltAcord(++valor);
                if (isEstudiant){
                    totals.setVotEstudiant(TDSLanguageUtils.getMessage("resposta4"));
                }
                break;
        }
        return totals;
    }
}
